import re
from datetime import datetime
from log import logger

REVERT_SAMPLE_KEYS = [
  'HOST_BYTES',
  'HOST_TCP_BYTES',
  'HOST_PKTS_COUNT',
  'HOST_SESSION_COUNT',
  'HOST_TCP_SESSION_COUNT',
  'HOST_HTTP_SESSION_COUNT',
  'HOST_WEB_DOMAIN_COUNT',
  'HOST_NEW_CALL_COUNT',
  'HOST_USER_HTTP_ADD_COUNT',
  'HOST_USER_TCP_ADD_COUNT',
  'HOST_USER_ACTIVE_COUNT',     
  'HOST_ACCESS_SRC_IP_COUNT',
  'HOST_SQL_COUNT',
  'HOST_SQL_ADD_COUNT',
  'HOST_SQL_ADD_SIZE_BYTES'
]

def calc_resource_index(cpu_usage, mem_usage, storage_usage):
  # CPU 资源利用率指数
  cpu_score = 100 * (1 - abs(cpu_usage - 50) / 50)
  
  # 内存资源利用率指数
  if 30 <= mem_usage <= 70: mem_score = 100
  elif mem_usage < 30: mem_score = 100 - ((0.3 - mem_usage / 100) * 100 / 0.3)
  else: mem_score = 100 - ((mem_usage / 100 - 0.7) * 100 / 0.3)
  if mem_score < 0: mem_score = 0

  # 存储资源利用率指数
  if 30 <= storage_usage <= 70: storage_score = 100
  elif storage_usage < 30: storage_score = 100 - ((0.3 - storage_usage / 100) * 100 / 0.3)
  else: storage_score = 100 - ((storage_usage / 100 - 0.7) * 100 / 0.3)
  if storage_score < 0: storage_score = 0

  # 计算最终的资源利用率指数 S
  # print(f'cpu_usage: {cpu_usage} mem_usage: {mem_usage} storage_usage: {storage_usage}')
  # print(f'cpu_score: {cpu_score} mem_score: {mem_score} storage_score: {storage_score}')
  S = cpu_score * 0.5 + mem_score * 0.3 + storage_score * 0.2
  # print(f'S: {S}')
  return S

def calc_performance_index(http_response_time, error_400_rate, error_500_rate):
  # HTTP 响应时间指数
  if http_response_time <= 1: t = 100
  elif http_response_time >= 3: t = 0
  else: t = (3 - http_response_time) / 2 * 100

  # HTTP 400 错误率指数
  if error_400_rate <= 1: r400 = 100
  elif error_400_rate >= 5: r400 = 0
  else: r400 = (5 - error_400_rate) / 4 * 100

  # HTTP 500 错误率指数
  if error_500_rate <= 0.1: r500 = 100
  elif error_500_rate >= 1: r500 = 0
  else: r500 = (1 - error_500_rate) / 0.9 * 100

  # 计算最终的业务性能指数 P
  P = t * 0.4 + r400 * 0.3 + r500 * 0.3
  return P

def calc_database_index(sql_response_time, sql_return_code_rate):
  # SQL 响应时间指数
  if sql_response_time <= 1: t = 100
  elif sql_response_time >= 3: t = 0
  else: t = (3 - sql_response_time) / 2 * 100

  # SQL 返回码指数
  if sql_return_code_rate <= 0.5: r = 100
  elif sql_return_code_rate >= 5: r = 0
  else: r = (5 - sql_return_code_rate) / 4.5 * 100

  # 计算最终的数据库效能指数 D
  D = t * 0.7 + r * 0.3
  return D

def calc_network_index(network_latency, packet_loss_rate, is_external=True):
  # 网络时延指数
  if is_external:
    if network_latency <= 50: latency_score = 100
    elif network_latency >= 200: latency_score = 0
    else: latency_score = (200 - network_latency) / 150 * 100

    # 丢包率指数
    if packet_loss_rate <= 1: loss_score = 100
    elif packet_loss_rate >= 5: loss_score = 0
    else: loss_score = (5 - packet_loss_rate) / 4 * 100
  else:
    if network_latency <= 10: latency_score = 100
    elif network_latency >= 100: latency_score = 0
    else: latency_score = (100 - network_latency) / 90 * 100

    # 丢包率指数
    if packet_loss_rate <= 0.1: loss_score = 100
    elif packet_loss_rate >= 1: loss_score = 0
    else: loss_score = (1 - packet_loss_rate) / 0.9 * 100

  # 计算最终的网络性能指数 N
  N = latency_score * 0.4 + loss_score * 0.6
  return N

def calc_efficiency_score(T, S, P, D=None, N=None, weight_resource=0.7, weight_performance=0.3):
  X = T * (S * weight_resource) * (P * weight_performance)
  if D is not None: X *= D
  if N is not None: X *= N
  # print(f'T: {T} S: {S} P: {P}')
  # print(f'X: {X}')
  return X

def calc_host_cloud_score(host_dict):
  # 计算效能
  cloud_resource_index = calc_resource_index(host_dict['HOST_CPU_AVG'], host_dict['HOST_MEM_AVG'], host_dict['HOST_DISK_AVG'])
  cloud_performance_index = calc_performance_index(host_dict['HOST_APP_RESPONSE_AVG'], host_dict['HOST_RETCODE_4xx_ERR_RATIO'], host_dict['HOST_RETCODE_5xx_ERR_RATIO'])
  cloud_database_index = calc_database_index(host_dict['HOST_SQL_RESPONSE_AVG'], host_dict['HOST_RETCODE_SQL_ERR_RATIO'])
  cloud_network_index = calc_network_index(float(host_dict['HOST_NET_DELAY_AVG']), host_dict['HOST_RETRANS_RATIO'])
  
  cpu_core = float(host_dict['HOST_CPU_CORE'])
  cpu_max  = float(host_dict['HOST_CPU_MAX'])
  tcp_session_count = float(host_dict["HOST_TCP_SESSION_COUNT"])
  
  if int(cpu_core) <= 0: cpu_core = 1.0
  if int(cpu_max)  <= 0: cpu_max  = 1.0
  
  energy_efficiency_ratio = tcp_session_count / (cpu_core * cpu_max)
  cloud_efficiency = calc_efficiency_score(energy_efficiency_ratio, cloud_resource_index, cloud_performance_index)
  
  host_dict['HOST_ENERGY_EFFICIENCY_RATIO'] = energy_efficiency_ratio
  host_dict['HOST_RESOURCE_INDEX'] = cloud_resource_index
  host_dict['HOST_PERFORMANCE_INDEX'] = cloud_performance_index
  host_dict['HOST_DATABASE_INDEX'] = cloud_database_index
  host_dict['HOST_NETWORK_INDEX'] = cloud_network_index
  host_dict['HOST_EFFICIENCY_SCORE'] = cloud_efficiency 

  if cpu_core <= 0: cpu_core = 1;
  if cpu_max > 0:
    host_dict["HOST_MAX_BUSI_LOAD"] = 0.8 * host_dict["HOST_TCP_SESSION_COUNT"] / cpu_max
  else:
    host_dict["HOST_MAX_BUSI_LOAD"] = 0

def create_host_val_dict(host, start, end):
  start_str = datetime.fromtimestamp(start).strftime("%Y-%m-%d %H:%M:%S")
  end_str   = datetime.fromtimestamp(end).strftime("%Y-%m-%d %H:%M:%S")
  return {
    # 必须字段
    "timestamp": start,
    "source": host,
    "message": host,
    "host": host,
    # 归档信息
    "ARCH_SIZE": 3600,
    "ARCH_TYPE": "HOST",
    "ARCH_START": start_str,
    "ARCH_END": end_str,
    # 流量与数据包
    "HOST_BYTES": 0,
    "HOST_TCP_BYTES": 0,
    "HOST_PKTS_COUNT": 0,
    "HOST_RETRANS_COUNT": 0,
    "HOST_RETRANS_RATIO": 0,
    # 全部会话、TCP握手
    "HOST_SESSION_COUNT": 0,
    "HOST_TCP_SESSION_COUNT": 0,
    "HOST_NET_DELAY_AVG": 0,
    # HTTP相关：会话、时延、返回码
    "HOST_HTTP_SESSION_COUNT": 0,
    "HOST_APP_RESPONSE_AVG": 0,
    "HOST_RETCODE_4xx_ERR_COUNT": 0,
    "HOST_RETCODE_4xx_ERR_RATIO": 0.0,
    "HOST_RETCODE_5xx_ERR_COUNT": 0,
    "HOST_RETCODE_5xx_ERR_RATIO": 0.0,
    "HOST_RETCODE_ERR_COUNT": 0,
    "HOST_RETCODE_ERR_RATIO": 0.0,
    # 数据库：SQL条数、新增、返回码
    "HOST_SQL_COUNT": 0,
    "HOST_SQL_ADD_COUNT": 0,
    "HOST_SQL_ADD_SIZE_BYTES": 0,
    "HOST_SQL_RESPONSE_AVG": 0,
    "HOST_RETCODE_SQL_ERR_COUNT": 0,
    "HOST_RETCODE_SQL_ERR_RATIO": 0.0,
    # 访问人数、人次、新增调用规模
    "HOST_ACCESS_IP_COUNT": 0,
    "HOST_NEW_CALL_COUNT": 0,
    "HOST_USER_HTTP_ADD_COUNT": 0,
    "HOST_USER_TCP_ADD_COUNT": 0,
    "HOST_USER_ACTIVE_COUNT": 0,     
    "HOST_ACCESS_SRC_IP_COUNT": 0,
    # 二次计算平均值和比率
    "HOST_PER_CPU_SESSION": 0,
    "HOST_NORMAL_RATIO": 0
  }

def create_system_host_val_dict(system, start, end):
  start_str = datetime.fromtimestamp(start).strftime("%Y-%m-%d %H:%M:%S")
  end_str   = datetime.fromtimestamp(end).strftime("%Y-%m-%d %H:%M:%S")
  return {
    # 必须字段
    "timestamp": start,
    "message": system,
    "host": system,
    # 归档信息
    "ARCH_SIZE": 3600,
    "ARCH_TYPE": "SYSTEM",
    "ARCH_START": start_str,
    "ARCH_END": end_str
  }

def calc_host_avg_ratio(val_dict):
  # 计算重传率
  if val_dict['HOST_PKTS_COUNT'] > 0:
    val_dict['HOST_RETRANS_RATIO'] = (val_dict['HOST_RETRANS_COUNT'] / val_dict['HOST_PKTS_COUNT']) * 100
  # 计算每个CPU核心数会话
  if val_dict['HOST_CPU_CORE'] > 0:
    val_dict['HOST_PER_CPU_SESSION'] = val_dict['HOST_SESSION_COUNT'] / int(val_dict['HOST_CPU_CORE'])
  # 计算是否正常存活，大于10K流量
  val_dict['HOST_NORMAL_RATIO'] = 0
  if val_dict['HOST_BYTES'] > 10240:
    val_dict['HOST_NORMAL_RATIO'] = 1
  # 计算HTTP错误返回码和错误率
  val_dict['HOST_RETCODE_ERR_COUNT'] = val_dict['HOST_RETCODE_4xx_ERR_COUNT'] + val_dict['HOST_RETCODE_5xx_ERR_COUNT']
  if val_dict['HOST_HTTP_SESSION_COUNT'] > 0:
    val_dict['HOST_RETCODE_ERR_RATIO'] = (val_dict['HOST_RETCODE_ERR_COUNT'] / val_dict['HOST_HTTP_SESSION_COUNT']) * 100
  # 计算SQL错误率
  if val_dict['HOST_SQL_COUNT'] > 0:
    val_dict['HOST_RETCODE_SQL_ERR_RATIO'] = (val_dict['HOST_RETCODE_SQL_ERR_COUNT'] / val_dict['HOST_SQL_COUNT']) * 100
